using System;
using System.IO;
using System.Collections;
using System.Windows.Forms;
// using System.Runtime.Serialization;
// using System.Runtime.Serialization.Formatters.Binary;

using MSHelpLib; 

namespace MSHelpLib.BaseCode
{
	/// <summary>
	/// Summary description for MSHelper.
	/// </summary>
	public class MSHelper
	{
        /// <summary>
        /// Initializes a new instance of the <see cref="MSHelper"/> class.
        /// </summary>
		public MSHelper()
		{
		}

		//-----------------------------------------------------------------------------------------------
		//
		//	Table Of Contents Helpers
		//
        /// <summary>
        /// Fills the tree.
        /// </summary>
        /// <param name="helpSystem">The help system.</param>
        /// <param name="treeCtrl">The tree CTRL.</param>
		public static void FillTree(MSHelpLib.IHelpSystem helpSystem, System.Windows.Forms.TreeView treeCtrl)
		{
			if (treeCtrl==null)
				return;

			if (helpSystem==null)
				return;

			if (helpSystem.TableOfContents==null)
				return;

			if (helpSystem.TableOfContents.TOC==null)
				return;

			if (helpSystem.TableOfContents.TOC.Count==0)
				return;

			treeCtrl.Nodes.Clear();
			foreach(TOCItem Item in helpSystem.TableOfContents.TOC)
			{
				FillTree(0, Item, treeCtrl.Nodes);
			}
		}

        /// <summary>
        /// Fills the tree.
        /// </summary>
        /// <param name="tableOfContents">The table of contents.</param>
        /// <param name="treeCtrl">The tree CTRL.</param>
		public static void FillTree(MSHelpLib.TableOfContents tableOfContents, System.Windows.Forms.TreeView treeCtrl)
		{
			if (treeCtrl==null)
				return;

			if (tableOfContents==null)
				return;

			if (tableOfContents.TOC==null)
				return;
			
			if (tableOfContents.TOC.Count==0)
				return;

			treeCtrl.Nodes.Clear();
			foreach(TOCItem Item in tableOfContents.TOC)
			{
				FillTree(0, Item, treeCtrl.Nodes);
			}
		}

		private static int TagCount=0;
		private static TOCItem m_PrevItem=null;
		private static void FillTree(int Level, TOCItem Item, TreeNodeCollection ParentNode)
		{	
			TreeNodeCollection ParentNodeCol=ParentNode;
			if (Item.MergeLink=="")
			{
				string Name=Item.Name;
				TreeNode NewNode=new TreeNode(Name);
				NewNode.Tag=Item;

				if (m_PrevItem!=null)
					m_PrevItem.Next=Item;

				Item.Prev=m_PrevItem;
				m_PrevItem=Item;
				
				Item.TagIndex=TagCount++;
				Item.treeNode=NewNode;			

				ParentNode.Add(NewNode);

				ParentNodeCol=NewNode.Nodes;

				if (Level<3)
					NewNode.Expand();
			}
			
			foreach(TOCItem ChildItem in Item.Children)
			{
				FillTree(Level+1, ChildItem,ParentNodeCol);
			}			
		}
		
		//-----------------------------------------------------------------------------------------------
		//
		//	Index Helpers
		//
		private static void AddChildren(IndexItem2 item, int Indent, System.Windows.Forms.ListBox lbIndex)
		{			
			item.Children.Sort(new MSHelpLib.BaseCode.SortIndexItems());
			foreach(IndexItem2 subItem in item.Children)
			{
                if (subItem.Title.Trim() == "")
                    continue;

				subItem.Indent=Indent;
				lbIndex.Items.Add(subItem);
				if (subItem.Children.Count>0)
					AddChildren(subItem,Indent+1,lbIndex);
			}
		}

        /// <summary>
        /// Builds the index.
        /// </summary>
        /// <param name="index">The index.</param>
        /// <param name="lbIndex">Index of the lb.</param>
		public static void BuildIndex(ArrayList index, System.Windows.Forms.ListBox lbIndex)
		{		
			if (index==null)
				return;
			if (lbIndex==null)
				return;

			lbIndex.Items.Clear();			
			int Indent=0;
			lbIndex.DisplayMember="IndexTitle";
			index.Sort(new MSHelpLib.BaseCode.SortIndexItems());
			foreach(IndexItem2 curItem in index)
			{
                if (curItem.Title.Trim() == "")
                    continue;
				if (lbIndex.Items.Contains(curItem))
					continue;

				// Add index item.
				curItem.Indent=Indent;				
				lbIndex.Items.Add(curItem);
				if (curItem.Children.Count>0)
					AddChildren(curItem,Indent+1,lbIndex);
			}			
		}

        /// <summary>
        /// Indexes the search.
        /// </summary>
        /// <param name="txtIndex">Index of the TXT.</param>
        /// <param name="lbIndex">Index of the lb.</param>
		public static void IndexSearch(string txtIndex, System.Windows.Forms.ListBox lbIndex)
		{
			int idx = -1;
			int Len=txtIndex.Length;
			string szText=txtIndex.Trim().ToLower();		
			foreach(IndexItem2 item in lbIndex.Items)
			{
				idx++;
				if (item.Indent>0)
					continue;
				string str=item.Title;
				str=str.ToLower();

				if (txtIndex.Length>str.Length)
					continue;

				if (str.Substring(0,Len)==szText)
				{
					item.bFlag=true;
					lbIndex.SelectedIndex = idx;					
					item.bFlag=false;
					return;
				}				
			}
		}

        /// <summary>
        /// Compacts the index.
        /// </summary>
        /// <param name="Index">The index.</param>
		public static void CompactIndex(ArrayList Index)
		{
			foreach(IndexItem2 item in Index)
			{
				ProcessIndexItem(null, item);
			}
		}

        /// <summary>
        /// Processes the index item.
        /// </summary>
        /// <param name="parent">The parent.</param>
        /// <param name="item">The item.</param>
        /// <returns></returns>
		public static int ProcessIndexItem(IndexItem2 parent, IndexItem2 item)
		{
			if (item.Children.Count>0)
			{				
				SortIndexItemsURL MyComparer=new SortIndexItemsURL();
				foreach(IndexItem2 subItem in item.Children)
				{
					int rc=ProcessIndexItem(item,subItem);
					if (rc==1)
						break;
				}

				if (item.Children.Count>1)
				{
					bool bRedo=false;
					do
					{
						bRedo=false;
						for(int i=item.Children.Count-1;i>=0;i--)
						{
							IndexItem2 subItem=(IndexItem2)item.Children[i];
							int idx=item.Children.BinarySearch(0,item.Children.Count,subItem,MyComparer);
							if ((idx>-1) && (i!=idx))
							{
								// Remove Duplicate index entry
								item.Children.RemoveAt(idx);		
								bRedo=true;
								break;
							}
						}
					}	
					while (bRedo==true);		
				}
			}
			else
			{
				// We are at the bottom of a branch				
				if ((parent!=null) && (parent.Children.Count==1) && (parent.Url==""))
				{
					// We are the only child of the parent.
					parent.Url=item.Url;
					parent.Children.Clear();
					return 1;
				}
			}
			return 0;
		}
	}
}
